﻿using WDE.Helpers;

namespace WDE
{
    using System;
    using OpenQA.Selenium;
    using OpenQA.Selenium.Interactions;
    using OpenQA.Selenium.Remote;

    public class Element
    {
        public Element(IWebElement element, IWebDriver driver)
        {
            El = element;
            Driver = driver;
            Id = element.GetAttribute("id");

            if (String.IsNullOrEmpty(Id))
            {
                Id = Guid.NewGuid().ToString();
                driver.ExcuteJs("$(arguments[0]).attr('id', arguments[1]);", element, Id);
            }
            
        }

        protected IWebDriver Driver { get;private set; }

        public IWebElement El { get; private set; }

        public string Text { get { return El.Text; }}

        protected string Id;

        public bool IsVisible
        {
            get
            {
                const string script = "return Ext.get(arguments[0]).isVisible()";
                return (bool)Driver.ExcuteJs(script, Id);
            }
        }

        public bool IsDisplayed
        {
            get
            {
                const string script = "return Ext.get(arguments[0]).isDisplayed()";
                return (bool)Driver.ExcuteJs(script, Id);
            }
        }

        public T FindBy<T>(By by, params object[] args) where T : Element
        {
            return Driver.FindBy<T>(by, El, args);
        }

        public T FindByJQuery<T>(Framework.jQuery.By.JQueryBy by, params object[] args) where T : Element
        {
            return Driver.FindByJQuery<T>(by, El, args);
        }
        /// <summary>
        /// Наведение курсора на элемент
        /// </summary>
        /// <returns>Возвращает элемент</returns>
        public Element MouseMoveToElement()
        {
            var remoteWebDriver = (RemoteWebDriver)Driver;
            var remoteWebElement = (RemoteWebElement)El;
            remoteWebDriver.Mouse.MouseMove(remoteWebElement.Coordinates);
            return this;
        }

        public Element Click()
        {
            var step = 0;
            while (step < 50)
            {
                try
                {

                    HighlightRed();
                    El.Click();
                    break;
                }
                catch (Exception)
                {

                }
                System.Threading.Thread.Sleep(100);
                step++;
            }
            return this;
        }

        public Element ContextClick()
        {
            var step = 0;
            while (step < 50)
            {
                try
                {
                    HighlightRed();
                    var action = new Actions(Driver);
                    action.ContextClick(El);
                    action.Perform();
                    El.Click();
                    break;
                }
                catch (Exception)
                {

                }
                System.Threading.Thread.Sleep(100);
                step++;
            }
            return this;
        }

        public Element DoubleClick()
        {
            var step = 0;
            while (step < 50)
            {
                try
                {
                    HighlightRed();
                    var action = new Actions(Driver);
                    action.DoubleClick(El);
                    action.Perform();
                    break;
                }
                catch (Exception)
                {
                }
                System.Threading.Thread.Sleep(100);
                step++;
            }
            return this;
        }

        protected object GetValue()
        {
            HighlightGreen();
            return El.Text;
        }

        protected void HighlightRed()
        {
            const string script = @"var s = $('#'+arguments[0]), el = $('<div/>').appendTo('body'), o = s.offset();
                            setTimeout(function(){el.css({ 'pointer-events':'none', 'border-radius':5, position: 'absolute', zIndex: 9999999999999, left: o.left-5, top: o.top-5, width: s.outerWidth()+10, height: s.outerHeight()+10, opacity: 1, background: 'red' })
                              .animate({ opacity: 0 }, function(){ el.remove();}); }, 100);";

            Driver.ExcuteJs(script, Id);
        }

        private void HighlightGreen()
        {
            const string script = @"var s = $('#'+arguments[0]), el = $('<div/>').appendTo('body'), o = s.offset();
                            setTimeout(function(){el.css({ 'pointer-events':'none', 'border-radius':5, position: 'absolute', zIndex: 9999999999999, left: o.left-5, top: o.top-5, width: s.outerWidth()+10, height: s.outerHeight()+10, opacity: 1, background: 'green' })
                              .animate({ opacity: 0 }, function(){ el.remove();}); }, 100);";

            Driver.ExcuteJs(script, Id);
        }
    }
}
